package com.zrj.auth.core.extensions.wechat;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.hutool.core.bean.BeanUtil;
import com.zrj.auth.core.userdetails.mobile.MemberUserDetailsServiceImpl;
import com.zrj.auth.pojo.dto.MemberAuthInfoDTO;
import com.zrj.auth.pojo.dto.MemberDTO;
import com.zrj.auth.service.IUmsMemberService;
import lombok.Data;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.HashSet;

/**
 * 微信认证提供者
 * @author zhaorujie
 */
@Data
public class WechatAuthenticationProvider implements AuthenticationProvider {

    private MemberUserDetailsServiceImpl userDetailsService;
    private WxMaService wxMaService;
    private IUmsMemberService umsMemberService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        WechatAuthenticationToken authenticationToken = (WechatAuthenticationToken) authentication;
        String code = (String) authenticationToken.getPrincipal();
        WxMaJscode2SessionResult sessionResult = null;
        try {
            sessionResult = wxMaService.getUserService().getSessionInfo(code);
        }catch (WxErrorException e) {
            e.printStackTrace();
        }
        String openid = sessionResult.getOpenid();
        MemberAuthInfoDTO memberAuthInfoDTO = umsMemberService.getByOpenid(openid);
        //如果不存在就创建新用户
        if (memberAuthInfoDTO == null) {
            String sessionKey = sessionResult.getSessionKey();
            String encryptedData = authenticationToken.getEncryptedData();
            String iv = authenticationToken.getIv();
            // 解密 encryptedData 获取用户信息
            WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
            MemberDTO memberDTO = new MemberDTO();
            BeanUtil.copyProperties(userInfo, memberDTO);
            memberDTO.setOpenid(openid);
            umsMemberService.addMember(memberDTO);
        }
        UserDetails userDetails = userDetailsService.loadUserByOpenid(openid);
        WechatAuthenticationToken result = new WechatAuthenticationToken(userDetails, new HashSet<>());
        result.setDetails(authentication.getDetails());
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return WechatAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
